
package com.hlkj.pay.app.pay.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.pay.IPayWayAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.vo.merchant.req.UpdateStatusReq;
import com.hlkj.pay.vo.pay.req.PayWayReq;

import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;

/**
 * @author HlpayTeam
 * @date 2024/09/23 11:36
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PayWayAppServiceImpl implements IPayWayAppService {

    private final IPayWayService payWayService;

    private final IBusinessLogService businessChangeLogService;

    @Override
    public CommonResult<Void> savePayWay(PayWayReq payWayReq) {
        log.info("savePayWay payWayReq:{}", JsonUtils.toJsonString(payWayReq));
        try {
            PayWayDO detail = payWayService.queryByCode(payWayReq.getCode());
            if (detail != null) {
                return CommonResult.error(PayResultCode.PAY_WAY_EXITS);
            }
            // 去掉名称校验
            // detail = payWayService.queryByName(payWayReq.getName());
            // if (detail != null) {
            // return CommonResult.error(PayResultCode.PAY_WAY_EXITS);
            // }
            detail = BeanUtil.copy(payWayReq, PayWayDO.class);
            PayEnums.SCENE_PAY_TYPE[] values = PayEnums.SCENE_PAY_TYPE.values();
            PayEnums.SCENE_PAY_TYPE payType = null;
            for (PayEnums.SCENE_PAY_TYPE scenePayType : values) {
                if (StrUtil.endWithIgnoreCase(payWayReq.getCode(),scenePayType.getCode())) {
                    payType = scenePayType;
                    break;
                }
            }
            if (payType != null) {
                detail.setSubType(payType.getType());
            }
            payWayService.save(detail);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("savePayWay fail payWayReq:{},message:{}", JsonUtils.toJsonString(payWayReq), e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }

    }

    @Override
    public CommonResult<Void> updatePayWay(PayWayReq payWayReq) {
        log.info("updatePayWay payWayReq:{}", JsonUtils.toJsonString(payWayReq));
        try {
            if (!StringUtils.hasText(payWayReq.getCode())) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            PayWayDO payWayDb = payWayService.queryByCode(payWayReq.getCode());
            if (payWayDb == null) {
                return CommonResult.error(PayResultCode.PAY_WAY_NOT_EXITS);
            }
            // 去掉名称校验
            // PayWayDO payWayDO = payWayService.queryByName(payWayReq.getName());
            // if (payWayDO != null && !payWayReq.getCode().equals(payWayDO.getCode())) {
            // return CommonResult.error(PayResultCode.PAY_WAY_EXITS);
            // }
            PayWayDO updatePayWayDO = BeanUtil.copy(payWayReq, PayWayDO.class);
            updatePayWayDO.setId(payWayDb.getId());
            payWayService.update(updatePayWayDO);
            // 变更日志
            businessChangeLog(payWayDb, updatePayWayDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updatePayWay fail payWayReq:{},message:{}", JsonUtils.toJsonString(payWayReq),e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delPayWay(String code) {
        log.info("delPayWay code:{}", code);
        try {
            if (!StringUtils.hasText(code)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            PayWayDO payWayDb = payWayService.queryByCode(code);
            if (payWayDb == null) {
                return CommonResult.error(PayResultCode.PAY_WAY_NOT_EXITS);
            }
            payWayService.del(code);
            // 变更日志
            PayWayDO payWayDO = BeanUtil.copy(payWayDb, PayWayDO.class);
            payWayDO.setDeleteFlag(Boolean.TRUE);
            businessChangeLog(payWayDb, payWayDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delPayWay fail code:{},message:{}", code, e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updatePayWayStatus(UpdateStatusReq commonUpdateStatusReq) {
        log.info("updatePayWayStatus commonUpdateStatusReq:{}", JsonUtils.toJsonString(commonUpdateStatusReq));
        try {
            PayWayDO payWayDb = payWayService.queryByCode(commonUpdateStatusReq.getCode());
            if (payWayDb == null) {
                return CommonResult.error(PayResultCode.PAY_WAY_NOT_EXITS);
            }
            payWayService.updatePayWayStatus(payWayDb.getCode(), commonUpdateStatusReq.getStatus());
            // 变更日志
            PayWayDO payWayDO = BeanUtil.copy(payWayDb, PayWayDO.class);
            payWayDO.setStatus(commonUpdateStatusReq.getStatus());
            businessChangeLog(payWayDb, payWayDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("updatePayWayStatus fail commonUpdateStatusReq:{},message:{}", JsonUtils.toJsonString(commonUpdateStatusReq), e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    /**
     * log object
     * 
     * @param beforePayWay
     * @param afterPayWay
     * @return
     */
    void businessChangeLog(PayWayDO beforePayWay, PayWayDO afterPayWay) {
        businessChangeLogService.addBusinessChangeLog(beforePayWay.getCode(), PayEnums.CHANGE_LOG_TYPE.PAY_WAY.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.PAY, beforePayWay,
                afterPayWay);
    }
}
